package icu.groot.alan.hotel.controller.order;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.Gson;
import icu.groot.alan.hotel.entity.dao.AccountDo;
import icu.groot.alan.hotel.entity.dao.OrderDo;
import icu.groot.alan.hotel.entity.dao.RoomDo;
import icu.groot.alan.hotel.entity.req.OrderGenerateRo;
import icu.groot.alan.hotel.entity.vo.OrderGenerateVo;
import icu.groot.alan.hotel.entity.vo.OrderListVo;
import icu.groot.alan.hotel.enums.OrderStatusEnum;
import icu.groot.alan.hotel.service.AccountService;
import icu.groot.alan.hotel.service.OrderService;
import icu.groot.alan.hotel.service.RoomService;
import icu.groot.alan.hotel.util.BizException;
import icu.groot.alan.hotel.util.GrootApi;
import icu.groot.alan.hotel.util.LoginTokenEntity;
import icu.groot.alan.hotel.util.ResultCodeEnum;
import icu.groot.alan.hotel.util.response.Result;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.UUID;

/**
 * Order Management
 */
@RestController
@RequestMapping("/order")
public class OrderController {
    @Resource
    OrderService orderService;

    @Resource
    RoomService roomService;

    @Resource
    AccountService accountService;

    @ApiOperation("Purchase")
    @PostMapping("/purchase/{orderCode}")
    public Result<String> purchase(@PathVariable("orderCode") String orderCode, HttpServletRequest request){
        if (orderCode == null || orderCode.equals("")){
            throw new BizException(ResultCodeEnum.FAILED.setMessage("缺失参数"));
        }
        LoginTokenEntity loginTokenEntity = new Gson().fromJson(request.getAttribute(GrootApi.Jwt.HEADER).toString(), LoginTokenEntity.class);
        orderService.purchase(orderCode, loginTokenEntity.getAccCode());
        return Result.success("预定成功", "");
    }

    @ApiOperation("Generate")
    @PostMapping("/generate")
    public Result<OrderGenerateVo> generate(@RequestBody OrderGenerateRo orderGenerateRo, HttpServletRequest request){
        isStringNull(orderGenerateRo.getCheckinStartTime());
        isStringNull(orderGenerateRo.getCheckinEndTime());
        isStringNull(orderGenerateRo.getCheckinName());
        isStringNull(orderGenerateRo.getCheckinIdentity());
        isStringNull(orderGenerateRo.getInformPhone());
        isStringNull(orderGenerateRo.getRoomType());
        LoginTokenEntity loginTokenEntity = new Gson().fromJson(request.getAttribute(GrootApi.Jwt.HEADER).toString(), LoginTokenEntity.class);
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime startTime, endTime;
        orderGenerateRo.setCheckinStartTime(orderGenerateRo.getCheckinStartTime() + " 14:00:00");
        orderGenerateRo.setCheckinEndTime(orderGenerateRo.getCheckinEndTime() + " 12:00:00");
        try {
            startTime = LocalDateTime.parse(orderGenerateRo.getCheckinStartTime(), df);
            endTime = LocalDateTime.parse(orderGenerateRo.getCheckinEndTime(), df);
        }catch (Exception e){
            throw new BizException(ResultCodeEnum.FAILED.setMessage("请求参数格式错误"));
        }
        // 判断日期要求是否合适
        if (startTime.isBefore(LocalDate.now().atStartOfDay()) || endTime.isBefore(startTime) || startTime.toLocalDate().equals(endTime.toLocalDate())){
            throw new BizException(ResultCodeEnum.FAILED.setMessage("选择的日期不对, 请重选"));
        }

        List<RoomDo> roomDos = roomService.list();
        List<OrderDo> orderDos = orderService.listByTime(startTime, endTime);
        for (OrderDo orderDo : orderDos) {
            for (RoomDo roomDo : roomDos) {
                if (orderDo.getRoomType().equals(roomDo.getRoomType())){
                    roomDo.setRoomSpareNum(roomDo.getRoomSpareNum() - 1);
                }
            }
        }
        RoomDo roomOne = null;
        for (RoomDo roomDo : roomDos) {
            if (roomDo.getRoomType().equals(orderGenerateRo.getRoomType())){
                if (roomDo.getRoomSpareNum() <= 0){
                    throw new BizException(ResultCodeEnum.FAILED.setMessage("该类房间已被抢完"));
                }
                roomOne = roomDo;
            }
        }

        OrderDo orderDo = new OrderDo();
        BeanUtils.copyProperties(orderGenerateRo, orderDo);
        orderDo.setOrderCode(UUID.randomUUID().toString());
        orderDo.setAccCode(loginTokenEntity.getAccCode());
        orderDo.setOrderStatus(OrderStatusEnum.UNPAID.toString());
        orderDo.setOrderReversePrice(BigDecimal.valueOf(Period.between(startTime.toLocalDate(), endTime.toLocalDate()).getDays()).multiply(roomOne.getRoomExp()));
        orderDo.setOrderEags(BigDecimal.valueOf(0));
        orderDo.setOrderStartTime(LocalDateTime.now());
        orderDo.setIsFinish(false);
        orderDo.setRoomType(roomOne.getRoomType());
        orderDo.setCheckinStartTime(startTime);
        orderDo.setCheckinEndTime(endTime);
        if (!orderService.save(orderDo)) {
            throw new BizException(ResultCodeEnum.SYSTEM_EXCEPTION);
        }
        OrderGenerateVo orderGenerateVo = new OrderGenerateVo();
        BeanUtils.copyProperties(orderDo, orderGenerateVo);
        orderGenerateVo.setCheckinStartTime(orderGenerateRo.getCheckinStartTime());
        orderGenerateVo.setCheckinEndTime(orderGenerateRo.getCheckinEndTime());
        return Result.success("预定成功", orderGenerateVo);

    }

    @ApiOperation("Select")
    @PostMapping("/list")
    public Result<List<OrderListVo>> list(HttpServletRequest request){
        LoginTokenEntity loginTokenEntity = new Gson().fromJson(request.getAttribute(GrootApi.Jwt.HEADER).toString(), LoginTokenEntity.class);
        QueryWrapper<OrderDo> orderDoQueryWrapper = new QueryWrapper<>();
        orderDoQueryWrapper.eq("acc_code", loginTokenEntity.getAccCode());
        orderDoQueryWrapper.orderByAsc(true, "order_start_time");
        List<OrderDo> list = orderService.list(orderDoQueryWrapper);
        List<OrderListVo> orderListVos = GrootApi.BeanCopy.convertListTo(list, OrderListVo::new);
        return Result.success(orderListVos);

    }

    @ApiOperation("Refund")
    @PostMapping("/refund/{orderCode}")
    public Result<String> refund(@PathVariable("orderCode") String orderCode, HttpServletRequest request){
        LoginTokenEntity loginTokenEntity = new Gson().fromJson(request.getAttribute(GrootApi.Jwt.HEADER).toString(), LoginTokenEntity.class);
        OrderDo one = orderService.getOne(new QueryWrapper<OrderDo>().eq("order_code", orderCode).eq("acc_code", loginTokenEntity.getAccCode()));
        if (one == null){
            throw new BizException(ResultCodeEnum.FAILED.setMessage("查无此订单"));
        }
        if (one.getOrderStatus().equals(OrderStatusEnum.OCCUPANCY.getStatus())){
            throw new BizException(ResultCodeEnum.FAILED.setMessage("已入住不可取消"));
        }
        if (one.getOrderStatus().equals(OrderStatusEnum.FINISH.getStatus())){
            throw new BizException(ResultCodeEnum.FAILED.setMessage("该订单已结束不可操作"));
        }
        if (one.getOrderStatus().equals(OrderStatusEnum.REFUND.getStatus())){
            throw new BizException(ResultCodeEnum.FAILED.setMessage("该订单退款"));
        }
        LocalDateTime now = LocalDateTime.now();
        long l = Duration.between(one.getOrderStartTime(), now).toMinutes();
        AccountDo byId = accountService.getById(loginTokenEntity.getAccCode());
        RoomDo roomOne = roomService.getOne(new QueryWrapper<RoomDo>().eq("room_type", one.getRoomType()));
        if (l < 30){
            BigDecimal orderReversePrice = one.getOrderReversePrice();
            one.setOrderStatus(OrderStatusEnum.REFUND.getStatus());
            byId.setAccBalance(byId.getAccBalance().add(orderReversePrice));
            orderService.updateById(one);
            accountService.updateById(byId);
            return Result.success("30分钟内退款成功:退还金额(全额)" + orderReversePrice.toString(), "");
        }
        one.setOrderStatus(OrderStatusEnum.REFUND.getStatus());
        BigDecimal refundPrice = one.getOrderReversePrice().subtract(roomOne.getRoomExp());
        byId.setAccBalance(byId.getAccBalance().add(refundPrice));
        orderService.updateById(one);
        accountService.updateById(byId);
        return Result.success("超时30分钟退款成功(扣去首日房费):退还金额" + refundPrice.toString(), "");
    }


    public static void main(String[] args) {
        System.out.println(System.currentTimeMillis()/1000);
        // 1677513600000
        //1.具有转换功能的对象
        String inputStringTime = "2023-02-28";
        String stringTime = inputStringTime.trim() + " 14:00:00";

        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        LocalDateTime localDateTime = LocalDateTime.parse(stringTime,df);

        long timeLong = localDateTime.toEpochSecond(ZoneOffset.ofHours(8));



        System.out.println(System.currentTimeMillis());
        System.out.println(timeLong);
        System.out.println();
        LocalDateTime localDateTime1 = LocalDateTime.ofInstant(Instant.ofEpochSecond(timeLong), ZoneId.systemDefault());
        System.out.println(localDateTime1);
        LocalDate localDate = localDateTime1.toLocalDate();
        System.out.println(localDate);


////2.要转换的对象
//        LocalDateTime time = LocalDateTime.now();
//
////3.发动功能
//        String localTime = df.format(time);
//        System.out.println("LocalDateTime转成String类型的时间："+localTime);

        while (true){
            System.out.println("轮播图第一张");
        }

    }

    private void isStringNull(String val){
        if (val == null || val.equals("")){
            throw new BizException(ResultCodeEnum.FAILED.setMessage("参数缺失"));
        }
    }

}
